﻿// <copyright file="Fields.cs" company="Microsoft Corporation">
// Copyright (c) 2009 Microsoft Corporation All Rights Reserved
// </copyright>
// <author>Michael S. Scherotter</author>
// <email>mischero@microsoft.com</email>
// <date>2009-03-25</date>
// <summary>Extension functions for OpenSocial objects with fields</summary>

namespace Synergist
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.Windows.Browser;
    using System.Windows.Media.Imaging;

    /// <summary>
    /// Extension object for JavaScript objects
    /// </summary>
    public static class Fields
    {
        /// <summary>
        /// get a field value as a string
        /// </summary>
        /// <param name="scriptObject">the implicit ScriptObject</param>
        /// <param name="key">the key to lookup</param>
        /// <returns>the value as a string</returns>
        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "get", Justification = "Mirroring opensocial API."), 
         SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Calling a JavaScript function may cause an exception.")]
        public static object getField(this ScriptObject scriptObject, string key)
        {
            if (scriptObject == null)
            {
                return null;
            }

            try
            {
                var keyName = key.Eval();

                object value = scriptObject.Invoke("getField", keyName);

                return value;
            }
            catch (System.Exception se)
            {
                System.Diagnostics.Debug.WriteLine(se);

                return null;
            }
        }

        /// <summary>
        /// Gets an image field
        /// </summary>
        /// <param name="scriptObject">the implicit ScriptObject</param>
        /// <param name="key">the key in the person class</param>
        /// <returns>a BitmapImage or null</returns>
        [SuppressMessage("Microsoft.Globalization", "CA1309:UseOrdinalStringComparison", MessageId = "System.String.EndsWith(System.String,System.StringComparison)", Justification = "Not relevant for Silverlight.")]
        public static BitmapImage GetImageField(this ScriptObject scriptObject, string key)
        {
            var uriString = getField(scriptObject, key) as string;

            if (uriString == null)
            {
                return null;
            }

            // Silverlight only supports JPEG and PNG images.
            if (uriString.EndsWith(".gif", StringComparison.InvariantCultureIgnoreCase))
            {
                return null;
            }

            System.Diagnostics.Debug.WriteLine("Creating Bitmap Image for {0}", uriString);

            var uri = new Uri(uriString, UriKind.Absolute);

            return new BitmapImage(uri);
        }

        /// <summary>
        /// Gets a field as a nullable date
        /// </summary>
        /// <param name="scriptObject">the script object</param>
        /// <param name="key">the field key</param>
        /// <returns>a nullable DateTime</returns>
        public static DateTime? GetDateField(this ScriptObject scriptObject, string key)
        {
            var date = scriptObject.getField(key) as string;

            if (string.IsNullOrEmpty(date))
            {
                return null;
            }

            return DateTime.Parse(date, CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// Gets a UriField
        /// </summary>
        /// <param name="scriptObject">the implicit scriptObject</param>
        /// <param name="key">the key for the person field</param>
        /// <returns>a Uri or null</returns>
        public static Uri GetUriField(this ScriptObject scriptObject, string key)
        {
            var uriString = scriptObject.getField(key) as string;

            if (uriString == null)
            {
                return null;
            }

            return new Uri(uriString, UriKind.Absolute);
        }

        /// <summary>
        /// Gets a field collection
        /// </summary>
        /// <param name="scriptObject">the scriptObject</param>
        /// <param name="key">the field key</param>
        /// <returns>an enumerable collection of script objects</returns>
        public static IEnumerable<ScriptObject> GetFieldCollection(this ScriptObject scriptObject, string key)
        {
            var value = getField(scriptObject, key) as ScriptObject;

            return new opensocial.ScriptArrayCollection(value);
        }

        /// <summary>
        /// Gets a field as an array of strings
        /// </summary>
        /// <param name="scriptObject">the JavaScript object</param>
        /// <param name="fieldName">the field name</param>
        /// <returns>an enumerable collection of string</returns>
        public static IEnumerable<string> GetStringArrayField(this ScriptObject scriptObject, string fieldName)
        {
            var fieldValue = scriptObject.getField(fieldName) as ScriptObject;

            if (fieldValue == null)
            {
                return null;
            }

            double number = (double)fieldValue.GetProperty("length");

            int length = System.Convert.ToInt32(number);

            string[] fieldArray = new string[length];

            for (var i = 0; i < length; i++)
            {
                fieldArray[i] = fieldValue.GetProperty(i) as string;
            }

            return fieldArray;
        }
    }
}
